#include <dt_db.hpp>
#include <iostream>
using namespace std;


static shared_ptr<DtDb> pDtDb;

shared_ptr<DtDb> confdb_getInstance(){

    if(nullptr == pDtDb){
        pDtDb.reset(new DtDb());
    }
    return pDtDb;
}

mutex m_cdataDbMutex;


DtDb::DtDb(){
    m_pSqliteDB = nullptr;
    m_dbLock = false;
}

DtDb::~DtDb(){

}


void DtDb::open(string dbFullName){
    m_dbFullName = dbFullName;
   // DtDb::close();
   lock_guard<mutex> gl(m_dbMu);
   if(nullptr == m_pSqliteDB)
        m_pSqliteDB = new SqliteDB(dbFullName);
}
    
void DtDb::close(){
    lock_guard<mutex> gl(m_dbMu);
    if(nullptr == m_pSqliteDB){
        
    }else{
        m_pSqliteDB->close();
        delete m_pSqliteDB;
    }
    m_pSqliteDB = nullptr;
}

void DtDb::db_lock(){
    lock_guard<mutex> gl(m_dbMu);
    m_dbLock = true;
}

void DtDb::db_unlock(){
    lock_guard<mutex> gl(m_dbMu);
    m_dbLock = false;
}

bool DtDb::db_islock(){
    bool ret = false;
    lock_guard<mutex> gl(m_dbMu);
    ret = m_dbLock;
    return ret;
}
string DtDb::getDBfullName()
{
    return m_dbFullName;
}
void DtDb::test_db(){
    lock_guard<mutex> gl(m_dbMu);
    if(nullptr == m_pSqliteDB){
        return;
    }

     try{
        #if 1
        std::string sql = "CREATE TABLE device_autotest (id INTEGER, type INTEGER NOT NULL DEFAULT 0, devid INTEGER, sn TEXT NOT NULL DEFAULT 0, pdevid INTEGER DEFAULT 0, model TEXT, name TEXT DEFAULT '设备', des TEXT, online INTEGER, param TEXT DEFAULT \"{}\", PRIMARY KEY (id AUTOINCREMENT))";
        std::weak_ptr<PreparedStatement> st = m_pSqliteDB->createPreparedStatement(sql);

        std::shared_ptr<PreparedStatement> stmt = st.lock();
       
        int ret = stmt->update();
        if( ret != SQLITE_OK && ret != SQLITE_DONE){
            printf("DtDb::test_db==============================================>\n");
        }
        #endif
    }catch(exception& e){
      
    }
}





int  DtDb::get_channels(vector<shared_DChannelPtr>& chs){
    lock_guard<mutex> gl(m_dbMu);
    if(nullptr == m_pSqliteDB){
        return -1;
    }

    try{
        std::string sql("select * from channel");
        std::weak_ptr<PreparedStatement> st = m_pSqliteDB->createPreparedStatement(sql);
        std::shared_ptr<PreparedStatement> stmt = st.lock();
        int ret;
        QueryResultRowSet begin, end;
        std::tie(ret, begin, end) = stmt->query();
        if( ret != SQLITE_OK ){
            return -1;
        }
        chs.clear();
        for(; begin != end; ++begin){
            shared_DChannelPtr pCh(new data_channel());
            auto col = *begin;
            pCh->id = col.getColumn<std::int64_t>(0);
            pCh->chid = col.getColumn<std::int32_t>(1);
            pCh->drvtype = col.getColumn<std::int32_t>(2);

            pCh->drvtype = col.getColumn<std::int32_t>(3);
            pCh->drvname = col.getColumn<std::string>(4);
            pCh->enable = col.getColumn<std::int32_t>(5);
            pCh->interval = col.getColumn<std::int32_t>(6);
            pCh->timeout = col.getColumn<std::int32_t>(7);
            pCh->trycnts = col.getColumn<std::int32_t>(8);
            pCh->param = col.getColumn<std::string>(9);
            pCh->des = col.getColumn<std::string>(10);
            chs.push_back(pCh);
        }
    }catch(exception& e){
         return -1;
    }
    return 0;
}

int  DtDb::get_channel_dps(vector<shared_DChanneldpPtr>& chDps){
lock_guard<mutex> gl(m_dbMu);
    if(nullptr == m_pSqliteDB){
        return -1;
    }
    try{
        std::string sql("select * from channel_dp");
        std::weak_ptr<PreparedStatement> st = m_pSqliteDB->createPreparedStatement(sql);
        std::shared_ptr<PreparedStatement> stmt = st.lock();
        int ret;
        int i = 0;
        QueryResultRowSet begin, end;
        std::tie(ret, begin, end) = stmt->query();
        if( ret != SQLITE_OK ){
            return -1;
        }
        chDps.clear();
        //return -1;
        for(; begin != end; ++begin){
            shared_DChanneldpPtr pCh(new data_channeldp());
            auto col = *begin;
            i = 0;
            pCh->id = col.getColumn<std::int64_t>(i++);
            pCh->dpid = col.getColumn<std::int32_t>(i++);
            pCh->chid = col.getColumn<std::int32_t>(i++);
            pCh->colid = col.getColumn<std::int32_t>(i++);
            pCh->devid = col.getColumn<std::int32_t>(i++);
            pCh->tag = col.getColumn<std::string>(i++);
            pCh->iotype = col.getColumn<std::int32_t>(i++);
            pCh->vtype = col.getColumn<std::int32_t>(i++);
            pCh->rvtype = col.getColumn<std::int32_t>(i++);
            pCh->bd = col.getColumn<std::int32_t>(i++);
            pCh->rw = col.getColumn<std::int32_t>(i++);
            pCh->exp = col.getColumn<std::string>(i++);
            pCh->upload = col.getColumn<std::int32_t>(i++);
            pCh->enable = col.getColumn<std::int32_t>(i++);
            pCh->param = col.getColumn<std::string>(i++);
            pCh->des = col.getColumn<std::string>(i++);
            chDps.push_back(pCh);
        }
     }catch(exception& e){
         return -1;
    }
    return 0;
}


int  DtDb::get_channel_dps(int chid,vector<shared_DChanneldpPtr>& chDps){
    lock_guard<mutex> gl(m_dbMu);
    if(nullptr == m_pSqliteDB){
        return -1;
    }
    try{
        std::string sql("select * from channel_dp where chid = ?");
        std::weak_ptr<PreparedStatement> st = m_pSqliteDB->createPreparedStatement(sql);
        std::shared_ptr<PreparedStatement> stmt = st.lock();
        int ret;
        int i = 0;
        QueryResultRowSet begin, end;
        std::tie(ret, begin, end) = stmt->query(chid);
        if( ret != SQLITE_OK ){
            return -1;
        }
        chDps.clear();
        //return -1;
        for(; begin != end; ++begin){
            shared_DChanneldpPtr pCh(new data_channeldp());
            auto col = *begin;
            i = 0;
            pCh->id = col.getColumn<std::int64_t>(i++);
            pCh->dpid = col.getColumn<std::int32_t>(i++);
            pCh->chid = col.getColumn<std::int32_t>(i++);
            pCh->colid = col.getColumn<std::int32_t>(i++);
            pCh->devid = col.getColumn<std::int32_t>(i++);
            pCh->tag = col.getColumn<std::string>(i++);
            pCh->iotype = col.getColumn<std::int32_t>(i++);
            pCh->vtype = col.getColumn<std::int32_t>(i++);
            pCh->rvtype = col.getColumn<std::int32_t>(i++);
            pCh->bd = col.getColumn<std::int32_t>(i++);
            pCh->rw = col.getColumn<std::int32_t>(i++);
            pCh->exp = col.getColumn<std::string>(i++);
            pCh->upload = col.getColumn<std::int32_t>(i++);
            pCh->enable = col.getColumn<std::int32_t>(i++);
            pCh->param = col.getColumn<std::string>(i++);
            pCh->des = col.getColumn<std::string>(i++);
            chDps.push_back(pCh);
        }
     }catch(exception& e){
         return -1;
    }
    return 0;
}
